<?php
/*
 * Copyright (c) Taras Kudla, 2010
 */

# last checking: 16.03.2010, status:worked
class ibase extends kernel implements dbostruct{ 
	private $connection=null;
	# basic ibase object contstruct
	public function init(){
		if(!extension_loaded("interbase")){
			$this->core->error("DBO_ibase","Cannot found ibase PHP module");
		}
	}
	
	function __destruct(){
	
	}

	public function connect($serv,$db,$user,$passwd){
		
		if( strlen($serv)==0 ) $serv="localhost";
		$host=$serv.":".$db;
		
		if($this->core->get("dbopersistent")){
			$c=@ibase_pconnect($host,$user,$passwd);
		}else {
			
			$c=@ibase_connect($host,$user,$passwd);
		}
		if(! is_resource($c)){
			$this->core->error("DBO_DRIVER_CONNECT","CANNOT CONNECT TO THE `ibase` DATABASE SERVER. CHECK PARAMETERS PLEASE.");
		}else{
			$this->connection=&$c;
		}
	}

	public function disconnect(){
		if(is_resource($this->connection)) {
			ibase_close($this->connection);
		}
	}

	# main sql select method with result handling
	public function select($table, $fields = "*", $sql = null, $type = _RESULT_ASSOC){
		
		$limits=null;		
		if( preg_match("/limit\s+([0-9]{1,})\s*((offset|,)\s*([0-9]{1,}))?/i",$sql,$tmp) ){
			$limits = " FIRST ".$tmp[1]." ".(isset($tmp[4])?" SKIP ".$tmp[4]:null);
			$sql = preg_replace("/limit\s+([0-9]{1,})\s*((offset|,)\s*([0-9]{1,}))?/i","",$sql);
		}			
		$sql = "select $limits " . $fields . " from " . $table . " " . $sql;
		
		$q = @ibase_query($this->connection,$sql);
		if ($q == false){
			$this->core->error("DBO_DRIVER_SELECT", (is_resource($this->connection) ? pg_last_error($this->connection) : null));
			return false;
		}
		switch ($type){
            case _RESULT_ASSOC:
                return $this->sqlToAssoc($q);
                break;
            case _RESULT_LIST:
                return $this->sqlToList($q, $fields);
                break;
            case _RESULT_BOOL:
                return ((bool) ibase_fields_rows($q));
                break;
            case _RESULT_PAIRS:
                return $this->sqlToPairs($q);
                break;
            case _RESULT_NUMROW:
                return $this->sqlToNumRow($q);
                break;		
            case _RESULT_ROW:
                return $this->sqlToRow($q);
                break;
            case _RESULT_SINGLE:
	    	case _RESULT_ONE:
	    		return $this->sqlToSingle($q);
	    		break;	    
            default:
                return $this->sqlToAssoc($q);
        }
	}
	
	# sql result to simple array ( as list )
	private function &sqlToList(&$q, $fields){
		if (preg_match("/[,]/", $fields, $null)){
			$this->core->error("DBO_DRIVER_SELECT", "Error in results ordering as LIST. Field should be without comas.");
		return false;
		}
		$a = array();
		while($row=ibase_fetch_row($q)){
			$a[] = $row[0];
		}
		return $a;
	}


	private function sqlToSingle(&$q){
    	if( ibase_num_fields($q)== 1 ){
    		$q=ibase_fetch_row($q);
    		return $q[0];
    	}   
    	return null; 
    }

    # sql select result as associative array ( like dictionary in python )
	private function sqlToRow(&$q){
		//if (pg_num_rows($q) == 0)
		//	return array();
		return ibase_fetch_assoc($q);
	}

	# sql select result as numeric indexes array
	private function sqlToNumRow(&$q){
		//if (pg_num_rows($q) == 0)
		//	return array();
		return ibase_fetch_row($q);
	}

	# sql select result to array of pairs key=>value
	private function &sqlToPairs(&$q){
		$array = array();
		if (ibase_num_fields($q) != 2){
			$this->core->error("DBO", "Cannot build pairs for result. Fields number must be 2");
		return false;
		}
		while ($row = ibase_fetch_row($q)){
			$array[$row[0]] = $row[1];
		}
		return $array;
	}

	# sql select result to arrays of associative array
	private function &sqlToAssoc(&$q){
		$array = array();
		while ($row = ibase_fetch_assoc($q) ){
			$array[] = $row;
		}
		return $array;
	}

	# inserting records to sql table
	public function insert($table, array $data){
		if (!is_array($data) || count($data) < 1){
			return false;
		}
		$q = @ibase_query($this->connection,"INSERT INTO $table (".implode(",",array_keys($data)).") VALUES ('".implode("','",array_values($data))."')");
		if ($q == false){
			$this->core->error("DBO_DRIVER_INSERT", ibase_errormsg() );
		return false;
		}
		return true;
	}

	# updating table
	public function update($table, $sql){
		$sql = "update " . $table . " " . $sql;
		$q = @ibase_query($this->connection,$sql);
		if ($q == false){
			$this->core->error("DBO_DRIVER_UPDATE", ibase_errormsg() );
		return false;
		}
		return true;
	}

    # deleting from table  
	public function delete($table, $sql){
		$sql = "delete from " . $table . " " . $sql;
		$q = @ibase_query($this->connection,$sql);
		if ($q == false){
			$this->core->error("DBO_DRIVER_DELETE", ibase_errormsg() );
		}
		return $q;
	}

	# direct sql query
	public function direct($sql){
		$q = @ibase_query($this->connection,$sql);
		if ($q == false){
			$this->core->error("DBO_DRIVER_DIRECT", ibase_errormsg() );
			return false;
		}
		return $q;
	}
	
	public function version(){
		
		$data=null;//ibase_server_info($this->connection,IBASE_SVC_SERVER_VERSION);
		return $data;
	}
	
	public function droptable($table){
    		if( is_object($table) && get_class($table)=="sqltable"){
    			$table = $table->getname();
    		}
		$this->direct("DROP TABLE $table");
	}
	
	public function createtable(sqltable $map){
	
     	list($name,$fields,$keys,$encoding,$engine) = $map->get();    	
      	$pkeys =array();
      	foreach( $keys as $k=>$v ){
      		if( $v[0]==_KEY_PRIMARY) $pkeys[]=$v[1];
      	}
      	$text = "CREATE TABLE $name ( ";
      	# fields processing      	
      	foreach( $fields as $k=>$v){
      		list($fname,$ftype,$fsize,$fdefault) = $v;
      		$fresult = $this->types($ftype,$fsize);
      		if( $ftype==_FIELD_TEXT && is_null($fdefault)) {
      			$default = " ";
      		} else if( ( $ftype==_FIELD_INT || $ftype==_FIELD_BIGINT || $ftype==_FIELD_TINYINT )  && is_null($fdefault)){
      			$default =" DEFAULT '0' ";
      		}  else {
      			$default =  !is_null($fdefault)?" DEFAULT '".$fdefault."' ":($ftype==_FIELD_INTAUTO?null:" NOT NULL ");
      		}
      		
      		
      		$text .=($k==0?null:" ,")." $fname $fresult ".($default).( in_array($fname,$pkeys)?" PRIMARY KEY ":null ) ." ";
      	}
      	$text .=" ) ";
      	if( $map->droponexist){
      		//$this->direct("DROP TABLE $name");
      	}
      	$this->direct($text);  	
      	# keys processing
      	foreach( $keys as $k=>$v){
      		$query = null;
      		list($ktype,$kfield) = $v;
      		$keydata = null;      		
      		switch( strtolower($ktype) ){
      			case _KEY_INDEX  : $keydata = "INDEX"; break;
      			case _KEY_UNIQUE : $keydata = "UNIQUE INDEX"; break;
  			
      		}    		
      		if( !is_null($keydata)){
      			
      			$query = "CREATE $keydata $name"."_"."$kfield ON $name ( ".$kfield." ) ";
      			$this->direct($query);
      			
      		}
      	}
      	return true;	
	}
	
	private function types($type,$size=null){

		$result = null;
        switch ($type)
        {
            case _FIELD_INTAUTO:
                $result = " SERIAL ";
                break;
            case _FIELD_INT:
                $result = " INTEGER ";
                break;
            case _FIELD_BIGINT:
                $result = " BIGINT ";
                break;
            case _FIELD_TINYINT:
                $result = " SMALLINT ";
                break;
            case _FIELD_CHAR:
                $result = "VARCHAR(" . ($size != null ? (int) $size : "255") . ") ";
                break;
            case _FIELD_DATE:
                $result = "DATE";
                break;
            case _FIELD_DATETIME:
            	$result = "TIMESTAMP";
            	break;
            case _FIELD_TIMESTAMP:
            	$result = "TIMESTAMP";
            	break;
            case _FIELD_TIME:
            	$result = "TIME";
            	break;
            case _FIELD_FLOAT:
            	$result = "FLOAT";
            	break;               
            case _FIELD_REAL:
            	$result = "DOUBLE";
            	break;
            case _FIELD_DOUBLE:
            	$result = " DOUBLE ";
            	break;      	
            case _FIELD_TEXT:
                $result = " BLOB SUB_TYPE TEXT SEGMENT SIZE 100 ";
                break;
            case _FIELD_LONGTEXT:
            	$result = " BLOB SUB_TYPE TEXT SEGMENT SIZE 100 ";
            	break;
            case _FIELD_BOOL:
            	$result = "BOOLEAN";
            case _FIELD_BLOB:
            	$result = "BLOB";
            default:
                " VARCHAR(255)";
                break;

        }
        return $result;
	}		
	public function tableexists($tablename){
	
	}


	}
?>
